/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Game;

import BJBots.BotPlayerBJ;
import Cards.Deck;
import Cards.FrenchCard;
import Internationalization.LoadInternationalization;
import JDBC.JavaDataBase;
import Resources1.Settings;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

/**
 * Class BJGame. It can use to manage BlackJack Game
 * @author masterinftel11
 */
public class BJGame extends Game<FrenchCard, PlayerBJ>{
   
    private final PlayerBJ crupier = new PlayerBJ("Crupier");
    private final ArrayList<BotPlayerBJ> bots; //Contiene los jugadores
    private JavaDataBase jdb = new JavaDataBase();
    
    /**
     * Print a question about split
     */
    private void printsplit(String p, char c){
        if(c == 'P'){
            System.out.println(LoadInternationalization.getRB().getString("player") + p + (LoadInternationalization.getRB().getString("split")));
        }
        else{
            System.out.println("Bot... " + p + LoadInternationalization.getRB().getString("split"));
        }
        System.out.println(LoadInternationalization.getRB().getString("yes"));
        System.out.println(LoadInternationalization.getRB().getString("no"));
    }
    
    /**
     * Print state of Game
     */
    public void printstate(){
        System.out.println("*****************************************");
        for (PlayerBJ p : players){
            System.out.println(LoadInternationalization.getRB().getString("player") + ": " + p.getId() + "            " + p.points() + " " + LoadInternationalization.getRB().getString("points"));
            for(int i=0; i<p.getHand().size(); i++){
                System.out.println(" - " + p.getHand().get(i).toString());
            }  
            if(p.getSplit()){
            System.out.println(LoadInternationalization.getRB().getString("player") + ": " + p.getId() + LoadInternationalization.getRB().getString("extra") + p.extrapoints() + LoadInternationalization.getRB().getString("points"));
                for(int i=0; i<p.getExtraHand().size(); i++){
                    System.out.println(" - " + p.getExtraHand().get(i).toString());
                } 
            }            
        }
        for (BotPlayerBJ p : bots){
            System.out.println("Bot " + p.getId() + "            " + p.points() + " " + LoadInternationalization.getRB().getString("points"));
            for(int i=0; i<p.getHand().size(); i++){
                System.out.println(" - " + p.getHand().get(i).toString());
            }  
            if(p.getSplit()){
            System.out.println("Bot " + p.getId() + LoadInternationalization.getRB().getString("extra") + p.extrapoints() + LoadInternationalization.getRB().getString("points"));
                for(int i=0; i<p.getExtraHand().size(); i++){
                    System.out.println(" - " + p.getExtraHand().get(i).toString());
                } 
            }            
        }        
        System.out.println(crupier.getId() + "                      " + crupier.points() + " " + LoadInternationalization.getRB().getString("points"));
        for(int i=0; i<crupier.getHand().size(); i++){
            System.out.println(" - " + crupier.getHand().get(i).toString());
        }
        System.out.println("\n");
    }
    
    private String whowin(){
        String playerwin = null;
        int points = 0;
        
        for(int i=0; i<players.size(); i++){
            if((players.get(i).points() + players.get(i).extrapoints()) > points && (players.get(i).points() + players.get(i).extrapoints()) < 21 ){
                playerwin = players.get(i).getId();
                points = players.get(i).points() + players.get(i).extrapoints();
            }
        }
        for(int i=0; i<bots.size(); i++){
            if((bots.get(i).points() + bots.get(i).extrapoints()) > points && (players.get(i).points() + players.get(i).extrapoints()) < 21){
                playerwin = bots.get(i).getId();
                points = bots.get(i).points() + bots.get(i).extrapoints();
            }
        }    
        
        return playerwin;
    }
    
    
    /**
     * This method constructs deck from file and creates players.
     * 
     * @param deckfile  path where is the deck
     */
    public BJGame (String deckfile){
        super();
        bots = new ArrayList<>();

        //Cargamos la baraja
        try {
            Deck<FrenchCard> d = new Deck<>();
            String str;
            InputStream is = getClass().getResourceAsStream(deckfile);
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            while ((str = br.readLine()) != null){
                d.add(new FrenchCard(FrenchCard.Number.valueOf(str.split("\\s")[0]), FrenchCard.Suit.valueOf(str.split("\\s")[1])));
            }
            Collections.shuffle(d);
            this.deck = d;            
        } catch (IOException ex) {
            System.err.println(ex.toString());
        }
        try{
            jdb.insertStart(Settings.getPlayersBJ().size()+Settings.getBotsBJ().size(), "BLACKJACK");
            for (int i = 0; i<Settings.getPlayersBJ().size(); i++){
                players.add(new PlayerBJ(Settings.getPlayersBJ().get(i)));
                jdb.insertPlayer(Settings.getPlayersBJ().get(i), "PLAYER");            
            } 
            for (int i = 0; i<Settings.getBotsBJ().size(); i++){
                bots.add(new BotPlayerBJ(Settings.getBotsBJ().get(i)));
                jdb.insertPlayer(Settings.getPlayersBJ().get(i), "PLAYER");            
            }
        }
        catch(Exception e){
            System.out.println(e.toString());
        }
    }
    
    /**
     * This method starts Game
     */
    public void startGame() {
        playedCards.add(deck.takeCard()); //Pone una carta bocabajo el cupier
        
        /* Repartimos una carta a cada jugador */
        for (PlayerBJ p : players){
                p.addCardToHand(deck.takeCard());
        } 
        
        for (BotPlayerBJ b : bots){
                b.addCardToHand(deck.takeCard());
        }

        /* Cupier se reparte la suya */
        crupier.addCardToHand(deck.takeCard());

        //Se reparte otra carta a cada jugador
        for (PlayerBJ p : players){
            FrenchCard c = deck.takeCard();
            if(c.getRank().equals(p.getHand().get(0).getRank())){
                p.setSplit(true);
                p.addCardToExtraHand(c);
            }
            else{
                p.setSplit(false);
                p.addCardToHand(c);
            }
        }
        
        for (BotPlayerBJ b : bots){
            FrenchCard c = deck.takeCard();
            if(c.getRank().equals(b.getHand().get(0).getRank())){
                b.setSplit(true);
                b.addCardToExtraHand(c);
            }
            else{
                b.setSplit(false);
                b.addCardToHand(c);
            }
        }
        
        printstate();
        
        /* Comienzan las decisiones de los Jugadores */
        for (PlayerBJ p : players){
            if(p.getSplit()){
                printsplit(p.getId(), 'P');
                Scanner sc = new Scanner(System.in);
                switch (sc.nextInt()){
                    case 1:
                        break;
                    case 2:
                        p.setSplit(false);
                        p.addCardToHand(p.getExtraHand().get(0));
                        break;
                    default:
                        System.out.println(LoadInternationalization.getRB().getString("invalidOption"));
                        break;
                } 
            }
            p.myTurn(this);
        }
        
        /* Comienzan las decisiones de los Bots */
        for (BotPlayerBJ b : bots){
            if(b.getSplit()){
                printsplit(b.getId(), 'B');
                
                switch (b.decisionSplit(b.getHand().get(0).getRank().getCode())){
                    case 1:
                        break;
                    case 2:
                        b.setSplit(false);
                        b.addCardToHand(b.getExtraHand().get(0));
                        break;
                    default:
                        System.out.println(LoadInternationalization.getRB().getString("invalidOption"));
                        break;
                } 
            }
            b.myTurn(this);
        }
        crupier.cupierTurn(this);
        
        String playerwin = whowin();
        
        
        /** Inserta quien ha ganado y quien ha perdido **/
        for(int i=0; i<players.size(); i++){
            if(players.get(i).getId() == null ? playerwin != null : !players.get(i).getId().equals(playerwin))
                jdb.insertGame(players.get(i).getId(), 0);
        }
        for(int i=0; i<bots.size(); i++){
            if(bots.get(i).getId() == null ? playerwin != null : !bots.get(i).getId().equals(playerwin))
                jdb.insertGame(bots.get(i).getId(), 0);
        }    
        
        jdb.insertGame(playerwin, 1);
        jdb.disconnect();
        System.out.println("El jugador "+playerwin+" gana");
    }
}
